package qgs.ddjdispachingsystem.ddj.wcs.service.impl;
import com.ioserver.bean.Union_DataType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qgs.ddjdispachingsystem.ddj.ioserver.IOServerService;
import qgs.ddjdispachingsystem.ddj.wcs.entity.WeightingPLCEntity;
import qgs.ddjdispachingsystem.ddj.wcs.enums.IOServerEnum;
import qgs.ddjdispachingsystem.ddj.wcs.service.WeighingPLCService;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * @Author: 蔡翔
 * @Date: 2019/11/13 9:42
 * @Version 1.0
 */
@Service
public class WeighingPLCServiceImpl implements WeighingPLCService {
    @Autowired
    IOServerService ioServerService;

    private final static Logger logger = LoggerFactory.getLogger(WeighingPLCServiceImpl.class);


    @Override
    public Integer warehousingBegin(Integer type, Integer position) {
        String positionS = "";
        String end = "";
        if(type == 1 ){
            //代表入库开始（堆垛机开始之前）
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_IN_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Frist_End.getCollectionPointName();
                    //end = "Frist_End";
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_IN_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Second_End.getCollectionPointName();
                    //end = "Second_End";
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_IN_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Third_End.getCollectionPointName();
                    //end = "Third_End";
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_IN_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Fourth_End.getCollectionPointName();
                    //end = "Fourth_End";
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_IN_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Fifth_End.getCollectionPointName();
                    //end = "Fifth_End";
                    break;
                default :
                    System.out.println("未知平台入口");
            }
            Integer integer = -2;
            Integer integer1 = -2;
            try {
                //在任务发起的时候无论 end 是否为 true或false，都给他置为false （相当于一个重置）
                //todo 如果Lstart 与 end 同时存在是否有bug
                integer1 = ioServerService.setTagValue(end, "0", 4);
                Thread.sleep(100);
                integer = ioServerService.setTagValue(positionS, "1", 4);
            }catch (Exception e){
                return -1;
            }
            if(integer != 0 && integer1 != 0){
                integer = -2;
            }
            return integer;
        }else {
            //代表出库开始（堆垛机开始之后）
            switch(position)
            {
                case 1 :
                    positionS = IOServerEnum.Cargo_First_OUT_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Frist_End.getCollectionPointName();
                    //end = "Frist_End";
                    break;
                case 2 :
                    positionS = IOServerEnum.Cargo_Second_OUT_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Second_End.getCollectionPointName();
                    //end = "Second_End";
                    break;
                case 3 :
                    positionS = IOServerEnum.Cargo_Third_OUT_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Third_End.getCollectionPointName();
                    //end = "Third_End";
                    break;
                case 4 :
                    positionS = IOServerEnum.Cargo_Fourth_OUT_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Fourth_End.getCollectionPointName();
                    //end = "Fourth_End";
                    break;
                case 5 :
                    positionS = IOServerEnum.Cargo_Fifth_OUT_Start.getCollectionPointName();
                    end = IOServerEnum.Cargo_Fifth_End.getCollectionPointName();
                    //end = "Fifth_End";
                    break;
                default :
                    System.out.println("未知平台入口");
            }
            Integer integer = -2;
            Integer integer1 = -2;
            try {
                integer1 = ioServerService.setTagValue(end, "0", 4);
                Thread.sleep(100);
                integer = ioServerService.setTagValue(positionS, "1", 4);

            }catch (Exception e){
                return -1;
            }
            if(integer != 0 && integer1 !=0){
                integer = -2;
            }
            return integer;
        }
    }

    /**
     * 返回值
     *          null 代表为   输入的平台不存在 /  操作IOServer 异常
     *
     **/
    @Override
    public List<Character> getSensorAlarmMessage(Integer type) {
        String position = "";
        List<Character> cs = new ArrayList<Character>();
        switch(type)
        {
            case 1 :
                position = IOServerEnum.Cargo_Frist_Sensor_Fault.getCollectionPointName();
                break;
            case 2 :
                position = IOServerEnum.Cargo_Second_Sensor_Fault.getCollectionPointName();
                break;
            case 3 :
                position = IOServerEnum.Cargo_Third_Sensor_Fault.getCollectionPointName();
                break;
            case 4 :
                position = IOServerEnum.Cargo_Fourth_Sensor_Fault.getCollectionPointName();
                break;
            case 5 :
                position = IOServerEnum.Cargo_Fifth_Sensor_Fault.getCollectionPointName();
                break;
            default :
                position = null;
                System.out.println("未知平台入口");
        }
        if(position==null){
            return null;
        }
        try {
            Union_DataType.ByValue valueByName = ioServerService.getValueByName(position);
            Short value = valueByName.i2Val;
            String s = Integer.toBinaryString(Integer.parseInt(value.toString()));
            for(int i=0;i<s.length();i++){
                cs.add(s.charAt(i));
            }
            return cs;
        }catch (Exception e){
            logger.error("WeightPLCServiceImpl，170行代码 IOServer写入异常");
            return null;
        }
    }

    /**
     * 注意
     *      参数：
     *          type 代表 是哪个口子
     *          leixing
     *                   1 代表入库
     *                   2 代表出库
     *
     * */
    @Override
    public WeightingPLCEntity getCargoAllMessage(Integer type, Integer leixing) {
        WeightingPLCEntity weightingPLCEntity = new WeightingPLCEntity();
        String position = "";
        String weight = "";
        String height = "";
        String end = "";
        String senator = "";
        String L_Start = "";
        List<Character> cs = new ArrayList<Character>();
        List<Character> seList = new ArrayList<Character>();

        switch(type)
        {
            case 1 :
                position = IOServerEnum.Cargo_First_Fault.getCollectionPointName();
                weight = IOServerEnum.Cargo_First_Weight.getCollectionPointName();
                height = IOServerEnum.Cargo_First_Height.getCollectionPointName();
                end = IOServerEnum.Cargo_Frist_End.getCollectionPointName();
                senator = IOServerEnum.Cargo_Frist_Sensor_Fault.getCollectionPointName();
                //end = "Frist_End";
                //senator = "Frist_Sensor_Fault";
                L_Start = IOServerEnum.Cargo_First_IN_Start.getCollectionPointName();
                break;
            case 2 :
                position = IOServerEnum.Cargo_Second_Fault.getCollectionPointName();
                weight = IOServerEnum.Cargo_Second_Weight.getCollectionPointName();
                height = IOServerEnum.Cargo_Second_Height.getCollectionPointName();
                end = IOServerEnum.Cargo_Second_End.getCollectionPointName();
                senator = IOServerEnum.Cargo_Second_Sensor_Fault.getCollectionPointName();
                //end = "Second_End";
                //senator = "Second_Sensor_Fault";
                L_Start = IOServerEnum.Cargo_Second_IN_Start.getCollectionPointName();
                break;
            case 3 :
                position = IOServerEnum.Cargo_Third_Fault.getCollectionPointName();
                weight = IOServerEnum.Cargo_Third_Weight.getCollectionPointName();
                height = IOServerEnum.Cargo_Third_Height.getCollectionPointName();
                end = IOServerEnum.Cargo_Third_End.getCollectionPointName();
                senator = IOServerEnum.Cargo_Third_Sensor_Fault.getCollectionPointName();
                //end = "Third_End";
                //senator = "Third_Sensor_Fault";
                L_Start = IOServerEnum.Cargo_Third_IN_Start.getCollectionPointName();
                break;
            case 4 :
                position = IOServerEnum.Cargo_Fourth_Fault.getCollectionPointName();
                weight = IOServerEnum.Cargo_Fourth_Weight.getCollectionPointName();
                height = IOServerEnum.Cargo_Fourth_Height.getCollectionPointName();
                end = IOServerEnum.Cargo_Fourth_End.getCollectionPointName();
                senator = IOServerEnum.Cargo_Fourth_Sensor_Fault.getCollectionPointName();
                //end = "Fourth_End";
                //senator = "Fourth_Sensor_Fault";
                L_Start = IOServerEnum.Cargo_Fourth_IN_Start.getCollectionPointName();
                break;
            case 5 :
                position = IOServerEnum.Cargo_Fifth_Fault.getCollectionPointName();
                weight = IOServerEnum.Cargo_Fifth_Weight.getCollectionPointName();
                height = IOServerEnum.Cargo_Fifth_Height.getCollectionPointName();
                end = IOServerEnum.Cargo_Fifth_End.getCollectionPointName();
                senator = IOServerEnum.Cargo_Fifth_Sensor_Fault.getCollectionPointName();
                //end = "Fifth_End";
                //senator = "Fifth_Sensor_Fault";
                L_Start = IOServerEnum.Cargo_Fifth_IN_Start.getCollectionPointName();
                break;
            default :
                position = null;
                weight = null;
                height = null;
                end = null;
                senator = null;
                L_Start = null;
                System.out.println("未知平台入口");
        }
        if(position==null){
            return null;
        }

        Short value;
        Short heightS;
        Float weightS;
        Short senatorErr;
        //去ioserver 获取高度和重量。如果暂时没有，那么去轮询获取
        while (true){
            try {
                //以前是 等2s 去取数据 ，现在改成  读一个标志位 当它为true  ，我就去 读，，，，，开始
                String blagFlag = "";
                switch(type)
                {
                    case 1 :
                        blagFlag = "Admission_allow1";
                        break;
                    case 2 :
                        blagFlag = "Admission_allow2";
                        break;
                    case 3 :
                        blagFlag = "Admission_allow3";
                        break;
                    case 4 :
                        blagFlag = "Admission_allow4";
                        break;
                    case 5 :
                        blagFlag = "Admission_allow5";
                        break;
                    default :
                        blagFlag = null;
                        System.out.println("未知平台入口");
                }
                if(position==null){
                    return null;
                }

                if(leixing==1){
                    while (true){
                        try {
                            Thread.sleep(100);
                        }catch (Exception e){
                            logger.error("获取称重标志位，线程sleep异常。");
                        }
                        boolean blag = ioServerService.getValueByName(blagFlag).bitVal;
                        if(blag){
                            break;
                        }else {
                            continue;
                        }
                    }
                }

                //以前是 等2s 去取数据 ，现在改成  读一个标志位 当它为true  ，我就去 读，，，，，结束
                Thread.sleep(2000);

                //报错信息
                Union_DataType.ByValue valueByName = ioServerService.getValueByName(position);
                Union_DataType.ByValue valueByWeight = ioServerService.getValueByName(weight);
                Union_DataType.ByValue valueByHeight = ioServerService.getValueByName(height);
                Union_DataType.ByValue valueBySenator = ioServerService.getValueByName(senator);

                //报错
                value = valueByName.i2Val;
                //货物高度
                heightS = valueByHeight.i2Val;
                //货物重量
                weightS = valueByWeight.r4Val;
                //传感器错误
                senatorErr = valueBySenator.i2Val;

            }catch (Exception e){
                logger.error("WeightPLCServiceImpl，277行代码 IOServer写入异常");
                return null;
            }
            //无异常，并且得出结果
            if(!Short.toString(heightS).equals("0") && !Float.toString(weightS).equals("0")  && Short.toString(value).equals("0") && Short.toString(senatorErr).equals("0")){
                String s = Integer.toBinaryString(Integer.parseInt(value.toString()));
                for(int i=0;i<s.length();i++){
                    cs.add(s.charAt(i));
                }
                String se = Integer.toBinaryString(Integer.parseInt(senatorErr.toString()));
                for(int i=0;i<se.length();i++){
                    seList.add(se.charAt(i));
                }

                weightingPLCEntity.setSenatorFault(seList);
                weightingPLCEntity.setFault(cs);
                weightingPLCEntity.setHeight(heightS);
                weightingPLCEntity.setWeight(weightS);
                //status 0 代表成功
                weightingPLCEntity.setStatus(0);

                /*
                *  拿到称重结果后 不要马上 重置，等任务结束再重置。
                try {
                    //L_Start 和 end 不能同时为true
                    Integer integer1 = ioServerService.setTagValue(L_Start, "0", 4);

                    if(integer1 !=0){
                        logger.error("时间"+new Date()+",称重模块：称重成功，但是重置lstart 失败");
                    }
                }catch (Exception e){
                    logger.error("时间"+new Date()+",称重模块：称重成功，但是重置lstart 异常");
                    //status 3 代表IOServer写入异常
                    weightingPLCEntity.setStatus(3);
                }*/


                return weightingPLCEntity;
            }
            //有报警 或者异常 会把 这个平台 的 end 置为true，，lstart置为false
            else if(!Short.toString(value).equals("0") || !Short.toString(senatorErr).equals("0")){
                String s = Integer.toBinaryString(Integer.parseInt(value.toString()));
                for(int i=0;i<s.length();i++){
                    cs.add(s.charAt(i));
                }

                String se = Integer.toBinaryString(Integer.parseInt(senatorErr.toString()));
                for(int i=0;i<se.length();i++){
                    seList.add(se.charAt(i));
                }

                weightingPLCEntity.setSenatorFault(seList);

                weightingPLCEntity.setFault(cs);
                weightingPLCEntity.setHeight(heightS);
                weightingPLCEntity.setWeight(weightS);
                //status 1代表称重失败或者 传感器异常
                weightingPLCEntity.setStatus(1);
                try {
                    //L_Start 和 end 不能同时为true
                    Integer integer1 = ioServerService.setTagValue(L_Start, "0", 4);
                    Thread.sleep(100);
                    Integer integer = ioServerService.setTagValue(end, "1", 4);
                    if(integer != 0 && integer1 !=0){
                        logger.error("时间"+new Date()+",称重模块：1.称重出现异常的时候；2.IOServer写入失败");
                        //status 2 代表IOServer写入失败
                        weightingPLCEntity.setStatus(2);
                    }
                }catch (Exception e){
                    //todo 修改
                    logger.error("时间"+new Date()+",称重模块：1.称重出现异常的时候；2.IOServer写入异常");
                    //status 3 代表IOServer写入异常
                    weightingPLCEntity.setStatus(3);
                }

                return weightingPLCEntity;
            }
        }
    }
}